import type { GreasyForkElements } from '../../../../../types/constants/personalization/greasy_fork'
import type { ComponentStyleIdType } from '../../../../../types/interfaces'
import { BaseModule } from '../../../../../lib/abstract'
import {
  AppStyleCollections,
  ComponentStyleId,
  logger,
  PAGE_ELEMENTS,
  PROJECT_PREFIX,
  SUPPORTED_PLATFORMS,
} from '../../../../../types/constants'
import { getElementSelector } from '../../../../../types/constants/personalization/common'
import { ConfigManager } from '../../../../config_manager'

interface Config {
  enabled?: boolean
}

export class GreasyForkFeedbackGroup extends BaseModule {
  readonly id: string = 'greasy_fork_feedback_group'
  readonly styleId: string = ComponentStyleId[this.name]
  isInitialized: boolean = false
  readonly supportedPlatforms: string[] = ConfigManager.getInstance().moduleSupportedPlatforms(this.name)
  private static instance: GreasyForkFeedbackGroup
  elements: GreasyForkElements = PAGE_ELEMENTS[SUPPORTED_PLATFORMS.GREASY_FORK]
  private readonly containerSelector = getElementSelector(this.elements, 'COMMON_CONTAINER')
  // 不处理隐藏的讨论
  private readonly itemSelector = `.discussion-list-container:not(.${AppStyleCollections.Hide.ELEMENT})`
  private readonly itemFullSelector = `${this.containerSelector} ${this.itemSelector}`

  config: Config = {
    enabled: true,
  }

  get name(): ComponentStyleIdType {
    return 'GreasyForkFeedbackGroup'
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): GreasyForkFeedbackGroup {
    if (!GreasyForkFeedbackGroup.instance) {
      GreasyForkFeedbackGroup.instance = new GreasyForkFeedbackGroup()
    }
    return GreasyForkFeedbackGroup.instance
  }

  destroy(): void {
    try {
      // 1. 移除所有创建的 DOM 元素
      this.removeDivider()

      // 2. 标记状态
      this.isInitialized = false

      super.destroy()
    }
    catch (error: any) {
      logger.error(`[${this.name}] Error occurred during module destruction:`, error)
    }
  }

  core(): void {
    this.isInitialized = true

    this.loadConfig()

    if (!this.config.enabled)
      return

    this.groupCommentsByMonth()
  }

  onToggleCallback(_id: string, checked: boolean): void {
    super.onToggleCallback(_id, checked)
  }

  removeDivider(): void {
    $(`${this.containerSelector} .month-divider`).remove()
  }

  groupCommentsByMonth(): void {
    const monthGroups: Record<string, JQuery<HTMLElement>[]> = {}
    const $comments = $(this.itemFullSelector)

    if ($comments.length === 0) {
      this.removeDivider()
      return
    }

    // 1. 按月份分组并找出每个月份的最新评论
    $comments.each((_, comment) => {
      const $comment = $(comment)

      // 优先获取最新回复时间
      let datetimeText = $comment.find('.discussion-meta .discussion-meta-item .discussion-meta-item relative-time[datetime]').attr('datetime')

      // 如果没有最新回复时间，则使用创建时间
      if (!datetimeText)
        datetimeText = $comment.find('.discussion-meta .discussion-meta-item relative-time[datetime]').attr('datetime')

      if (!datetimeText)
        return

      const date = new Date(datetimeText)
      const yearMonth = `${date.getFullYear()}年${date.getMonth() + 1}月`
      if (!monthGroups[yearMonth]) {
        monthGroups[yearMonth] = []
      }

      // 按时间排序，确保数组第一个元素是最新评论
      monthGroups[yearMonth].push($comment)
      monthGroups[yearMonth].sort((a, b) => {
        // 获取评论A的时间（优先最新回复时间）
        const timeA = this.getCommentTimestamp(a)
        // 获取评论B的时间（优先最新回复时间）
        const timeB = this.getCommentTimestamp(b)
        return timeB.getTime() - timeA.getTime()
      })
    })

    // 2. 为每个月份的最新评论添加分割线
    Object.entries(monthGroups).forEach(([month, comments]) => {
      if (comments.length === 0)
        return

      const $newestComment = comments[0] // 最新评论
      const $divider = $(`
        <div class="month-divider">
          <span class="month-text">${month}</span>
          <span class="comment-count">${comments.length}条评论</span>
        </div>
      `)

      $divider.insertBefore($newestComment)
    })
  }

  getCommentTimestamp($comment: JQuery<HTMLElement>): Date {
    // 尝试获取最新回复时间
    const replyTime = $comment.find('.discussion-meta .discussion-meta-item:nth-child(2) relative-time[datetime]').attr('datetime')
    if (replyTime)
      return new Date(replyTime)

    // 回退到创建时间
    const createTime = $comment.find('.discussion-meta .discussion-meta-item:first-child relative-time[datetime]').attr('datetime')
    return new Date(createTime || 0)
  }

  refresh(): void {
    this.destroy()
    this.init()
  }

  applyConfig(config: Partial<Config>): void {
    super.updateConfig(config)

    this.groupCommentsByMonth()

    logger.info(`[${this.name}] Config updated and apply`, this.config)
  }

  public static styles(): string {
    return `
.month-divider {
  color: var(--${PROJECT_PREFIX}-theme-accent) !important;
  font-size: 14px !important;
}
`
  }

  getStyles(): string {
    return ``
  }
}
